home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
memory
/
xmem10
/
xmem.asm
< prev
next >
Wrap
Assembly Source File
|
1995-03-25
|
22KB
|
754 lines
;-----------------------------------------------------------------------
;Can't take credit for the ASM code here, found it on a local BBS.
;The author has beem lost in the mists of time.
;
;
.MODEL MEDIUM
EXTmemError EQU 7
XMSmemError EQU 8
ShortAdr EQU 0
LongAdr EQU 1
procname MACRO Pnam
PUBLIC _&Pnam&
_&Pnam& PROC FAR
ENDM
endproc MACRO Pnam
_&Pnam& ENDP
ENDM
pwrlolvl_TEXT SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:pwrlolvl_TEXT, DS:pwrlolvl_TEXT, ES:pwrlolvl_TEXT
SUBTTL (Local Procedure) XMS_setup - find a XMS driver.
PAGE+
EVEN
XMSwordByte LABEL BYTE
XMSword DW 0
XMSmoveSTRUC STRUC
Length DW 0
LengthX DW 0
SrcHandle DW 0
SrcOffset DW 0
SrcOffsetX DW 0
DestHandle DW 0
DestOffset DW 0
DestOffsetX DW 0
XMSmoveSTRUC ENDS
XMSmainGET XMSmoveSTRUC <>
XMSmainPUT XMSmoveSTRUC <>
XMSwordGET XMSmoveSTRUC <2,,,,,,OFFSET XMSword>
XMSwordPUT XMSmoveSTRUC <2,,,OFFSET XMSword>
XMSfunctAdr DW 0, 0
; Don't try to call this from your programs
XMS_setup PROC NEAR
PUSH DS
PUSH ES
PUSH BX
MOV AX,CS ; Set Data segment to the code
segment.
MOV DS,AX ;
MOV [XMSwordGET.DestOffsetX],AX ; Set up the move data
structures.
MOV [XMSwordPUT.SrcOffsetX],AX ;
MOV AX,4300H ; See if a XMS Driver Exists.
INT 2FH ;
CMP AL,80H ;
MOV AX,0 ;
JNE XMS_setup01 ; Return 0 if not.
MOV AX,4310H ; If so, set the driver's function
INT 2FH ; address.
MOV [XMSfunctAdr],BX ;
MOV [XMSfunctAdr+2],ES ;
MOV AX,1 ; Return 1.
XMS_setup01:
POP BX
POP ES
POP DS
RET
XMS_setup ENDP
SUBTTL LSHL - Shift an unsigned long left
PAGE+
;****************************************************************************
;*
;* Shift an unsigned long integer left n number of bits.
;*
;****************************************************************************
;
; Stack frame definition for void LSHL( unsigned long *SHLnumber, unsigned n
);
;
LSHLparms STRUC
DW 0, 0
DW 0
SHLadr DD ?
SHLn DW ?
LSHLparms ENDS
procname LSHL
PUSH BP
MOV BP,SP
PUSH BX
PUSH CX
PUSH DX
PUSH DS
LDS BX,SHLadr[BP]
MOV CX,SHLn[BP]
MOV AX,[BX] ; Get the long integer.
MOV DX,[BX+2] ;
LSHL_01:
SHL AX,1 ; Do the long shift.
RCL DX,1 ;
LOOP LSHL_01 ;
MOV [BX],AX ; Replace the addressed number.
MOV [BX+2],DX ;
POP DS
POP DX
POP CX
POP BX
POP BP
RET ; Exit
endproc LSHL
SUBTTL Extended Memory - Stack template for EXTget, EXTput
PAGE+
EXTgpparms STRUC
DW 0, 0
DW 0
extgpBase DW ?
extgpblk DW ?
extgpblkAdr DW ?
extgpBytes DW ?
extgpmemAdr DW ?
DW ?
EXTgpparms ENDS
SUBTTL Extended Memory - XMS - Return total XMS memory.
PAGE+
; Use this function to detect wether or not XMS driver installed
;
; Stack frame definition for unsigned XMS_available( void );
;
; The total XMS memory available (in 16k blocks) is returned.
;
procname XMS_available
PUSH BX
PUSH CX
PUSH DX
CALL XMS_setup ; Ensure XMS memory is set.
TEST AX,AX ;
JZ XMS_available01 ; Return zero if not.
MOV AH,08H ; Set the size function code.
CALL DWORD PTR CS:[XMSfunctAdr] ; Get the size.
TEST AX,AX ;
JZ XMS_available01 ;
MOV AX,DX ; Set available Kbytes.
SUB AX,64 ; Subtract out the HMA (HIMEM.SYS
bug).
JNC XMS_available01 ;
XOR AX,AX ; Set zero if underflow.
XMS_available01:
MOV CL,4 ; Divide Kbytes by 16 for blocks.
SHR AX,CL ;
POP DX
POP CX
POP BX
RET ; Exit
endproc XMS_available
SUBTTL Extended Memory - XMS - Return largest block XMS mem.
PAGE+
;
; Stack frame definition for unsigned XMSblk_available( void );
;
; The size of the largest block of XMS memory available,
; (in 16Kbyte blocks) is returned.
;
procname XMSblk_available
PUSH BX
PUSH CX
PUSH DX
CALL XMS_setup ; Ensure XMS memory is set.
TEST AX,AX ;
JZ XMSblk_available01 ; Return zero if not.
MOV AH,08H ; Set the size function code.
CALL DWORD PTR CS:[XMSfunctAdr] ; Get the size.
TEST AX,AX ;
JZ XMSblk_available01 ;
SUB DX,64 ; Subtract out the HMA (HIMEM.SYS
bug).
JNC XMSblk_available0X ;
XOR DX,DX ; Set zero if underflow.
XMSblk_available0X:
CMP AX,DX ;
JBE XMSblk_available01 ;
MOV AX,DX ; Set available Kbytes.
XMSblk_available01:
MOV CL,4 ; Divide Kbytes by 16 for blocks.
SHR AX,CL ;
POP DX
POP CX
POP BX
RET ; Exit
endproc XMSblk_available
SUBTTL Extended Memory - XMS De-allocate a memory block.
PAGE+
;
; Stack frame definition for int XMS_dealloc( int Hdl );
;
; Zero is returned if the operation fails, non-zero if success.
;
; its really important to do this, only other way to recover
; XMS blocks is to re-boot
XMSdealparms STRUC
DW 0, 0
DW 0
xmsdealHdl DW ?
XMSdealparms ENDS
procname XMS_dealloc
PUSH BP
MOV BP,SP
PUSH BX
PUSH DX
; CALL XMS_setup ; Ensure XMS memory is set.
; TEST AX,AX ;
; JZ XMS_dealloc01 ; Return zero if not.
MOV DX,xmsdealHdl[BP] ; Get the handle to de-allocate.
MOV AH,0AH ;
CALL DWORD PTR CS:[XMSfunctAdr] ; De-allocate it.
XMS_dealloc01:
POP DX
POP BX
POP BP
RET ; Exit
endproc XMS_dealloc
SUBTTL Extended Memory - XMS Allocate a memory block.
PAGE+
;
; Stack frame definition for int XMS_alloc( unsigned rsrvd, *size );
;
; rsrved and size are in 16K byte blocks.
; rsrved is mem set aside for EMS, generaly zero
;
; Zero is returned if the operation fails.
; Block (XMS) handle is returned if success.
;
; size - is reduced by the amount of XMS memory actually allocated.
;
XMSalparms STRUC
DW 0, 0
DW 0
xmsalrsrvd DW ?
xmsalsize DD ?
XMSalparms ENDS
procname XMS_alloc
PUSH BP
MOV BP,SP
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH ES
PUSH DS
MOV AX,CS ; Set the data segment to the code
MOV DS,AX ; segment.
MOV CX,4 ;
ADD xmsalrsrvd[BP],CX ; Subtract out the HMA (HIMEM.SYS
bug).
SHL xmsalrsrvd[BP],CL ; Convert reserved blocks to K-bytes.
LES DI,xmsalsize[BP] ; Load size address.
XOR AX,AX ;
MOV BX,ES:[DI] ; Get the requested size in blocks.
TEST BX,0F000H ; Check for more than 64 Megabytes.
JZ XMS_alloc01 ;
MOV BX,00FFFH ;
XMS_alloc01:
MOV CL,4 ;
SHL BX,CL ; Convert to K-Bytes.
MOV CX,BX ; In CX.
JZ XMS_alloc05 ; Return zero if no size requested.
; CALL XMS_setup ; Ensure XMS memory is set.
; TEST AX,AX ;
; JZ XMS_alloc05 ; Return zero if not.
XOR BX,BX ;
MOV AH,08H ; Set to Query Free XMS Memory.
CALL DWORD PTR [XMSfunctAdr] ;
SUB DX,xmsalrsrvd[BP] ; Subtract out reserved blocks.
JB XMS_alloc03 ; Ensure no borrow.
CMP AX,DX ;
JBE XMS_alloc02 ;
MOV AX,DX ;
XMS_alloc02:
MOV DX,AX ;
CMP AX,68 ; Ensure enough memory to allocate.
XMS_alloc03:
MOV AX,0 ;
JB XMS_alloc05 ; Exit if not.
CMP BL,80H ; Check for errors.
JE XMS_alloc05 ;
CMP BL,81H ;
JE XMS_alloc05 ;
CMP CX,DX ; Check actual against requested size.
JBE XMS_alloc04 ;
MOV CX,DX ; Set if actual < requested.
XMS_alloc04:
MOV DX,CX ; Set requested size.
MOV AH,09H ;
CALL DWORD PTR [XMSfunctAdr] ; Allocate it.
DEC AX ; Check for errors.
MOV AX,0 ;
JNZ XMS_alloc05 ;
MOV AX,CX ; Convert allocated size in KBytes
MOV CL,4 ; to allocated blocks.
SHR AX,CL ;
SUB ES:[DI],AX ; Subtract the blocks allocated.
MOV AX,DX ; Set to return the handle.
XMS_alloc05:
POP DS
POP ES
POP DI
POP DX
POP CX
POP BX
POP BP
RET ; Exit
endproc XMS_alloc
SUBTTL Extended Memory - XMS get, put Stack Frame definition
PAGE+
XMSgpparms STRUC
DW 0, 0
DW 0
xmsgpHdl DW ?
xmsgpblk DW ?
xmsgpblkAdr DW ?
xmsgpBytes DW ?
xmsgpmemAdr DD ?
XMSgpparms ENDS
SUBTTL Extended Memory - XMStoMem
PAGE+
;
; Stack frame definition for int XMStoMem( unsigned Handle,
; unsigned blk,
; unsigned blkAdr,
; unsigned Bytes,
; char *memAdr
; );
;
; XMSmemError is returned if the operation fails, Zero if success.
;
procname XMStoMem
PUSH BP
MOV BP,SP
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH ES
PUSH DS
MOV AX,CS ; Set Data Segment to Code Segment.
MOV DS,AX ;
MOV CX,xmsgpBytes[BP] ; Get the number of bytes to transfer.
LES BX,xmsgpmemAdr[BP] ; Get the memory address.
MOV DX,xmsgpHdl[BP] ; Get the XMS handle.
MOV [XMSmainGET.SrcHandle],DX ; Set it in the move structures.
MOV [XMSwordGET.SrcHandle],DX ;
XOR DX,DX ;
MOV DI,xmsgpblk[BP] ; Get the block number.
SHR DI,1 ; Form the 32 bit XMS address in
RCR DX,1 ; DI:DX.
SHR DI,1 ;
RCR DX,1 ;
ADD DX,xmsgpblkAdr[BP] ;
TEST CX,1 ; Check for an odd number of bytes
JZ XMStoMem02 ; to transfer.
DEC CX ; Decrement to an even number of
bytes.
TEST DX,1 ; Check for an odd XMS address.
JZ XMStoMem01 ;
; XMS address is odd.
; -------------------
DEC DX ;
MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
MOV [XMSwordGET.SrcOffsetX],DI ;
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
PUSH BX ;
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
POP BX ;
DEC AX ; Check for errors.
JNZ XMStoMem03 ; Error out if error.
MOV AX,[XMSword] ; Get the moved word.
MOV ES:[BX],AH ; Move the odd byte to memory.
INC BX ; Reset the memory address.
ADD DX,2 ; And the XMS address.
JMP XMStoMem02 ; Move the block.
XMStoMem01:
; XMS address is even.
; --------------------
ADD DX,CX ;
MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
SUB DX,CX ;
MOV [XMSwordGET.SrcOffsetX],DI ;
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
PUSH BX ;
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
POP BX ;
DEC AX ; Check for errors.
JNZ XMStoMem03 ; Error out if error.
MOV AX,[XMSword] ; Get the moved word.
XCHG DI,CX ;
MOV ES:[BX+DI],AL ; Move the odd byte to memory.
XCHG DI,CX ;
XMStoMem02:
JCXZ XMStoMem04 ; Avoid a zero byte move.
MOV XMSmainGET.Length,CX ; Set length for the move.
MOV XMSmainGET.DestOffset,BX ; Set Memory address.
MOV XMSmainGET.DestOffsetX,ES ;
MOV XMSmainGET.SrcOffset,DX ; Set XMS address.
MOV XMSmainGET.SrcOffsetX,DI ;
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSmainGET ; Set address of the move structure.
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
DEC AX ; Check for errors.
JZ XMStoMem05
XMStoMem03:
MOV AX,XMSmemError ; Set error code if error.
JMP XMStoMem05 ;
XMStoMem04:
XOR AX,AX ;
XMStoMem05:
POP DS
POP ES
POP DI
POP SI
POP DX
POP CX
POP BX
POP BP
RET ; Exit
endproc XMStoMem
SUBTTL Extended Memory - MemToXMS
PAGE+
;
; Stack frame definition for int MemToXMS( unsigned Handle,
; unsigned blk,
; unsigned blkAdr,
; unsigned Bytes,
; char *memAdr
; );
;
; XMSmemError is returned if the operation fails, Zero if success.
;
procname MemToXMS
PUSH BP
MOV BP,SP
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH ES
PUSH DS
MOV AX,CS ;
MOV DS,AX ;
MOV CX,xmsgpBytes[BP] ; Get the number of bytes to transfer.
LES BX,xmsgpmemAdr[BP] ; Get the memory address.
MOV DX,xmsgpHdl[BP] ; Get the XMS handle.
MOV [XMSmainPUT.DestHandle],DX ; Set it in the move structures.
MOV [XMSwordPUT.DestHandle],DX ;
MOV [XMSwordGET.SrcHandle],DX ;
XOR DX,DX ;
MOV DI,xmsgpblk[BP] ; Get the block number.
SHR DI,1 ; Form the 32 bit XMS address in
RCR DX,1 ; DI:DX.
SHR DI,1 ;
RCR DX,1 ;
ADD DX,xmsgpblkAdr[BP] ;
TEST CX,1 ; Check for an odd number of bytes
JZ MemToXMS02 ; to transfer.
DEC CX ; Decrement to an even number of
bytes.
TEST DX,1 ; Check for an odd XMS address.
JZ MemToXMS01 ;
; XMS address is odd.
; -------------------
DEC DX ;
MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
MOV [XMSwordGET.SrcOffsetX],DI ;
MOV [XMSwordPUT.DestOffset],DX ;
MOV [XMSwordPUT.DestOffsetX],DI ;
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
PUSH BX ;
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
POP BX ;
DEC AX ; Check for errors.
JNZ MemToXMS03 ; Error out if error.
MOV AH,ES:[BX] ; Get the odd memory byte.
MOV [XMSwordByte+1],AH ; Put it in the moved word.
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSwordPUT ; Set address of the move structure.
PUSH BX ;
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
POP BX ;
DEC AX ; Check for errors.
JNZ MemToXMS03 ; Error out if error.
INC BX ; Reset the memory address.
ADD DX,2 ; And the XMS address.
JMP MemToXMS02 ; Move the block.
MemToXMS01:
; XMS address is even.
; --------------------
ADD DX,CX ;
MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
MOV [XMSwordPUT.DestOffset],DX ;
SUB DX,CX ;
MOV [XMSwordGET.SrcOffsetX],DI ;
MOV [XMSwordPUT.DestOffsetX],DI ;
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
PUSH BX ;
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
POP BX ;
DEC AX ; Check for errors.
JNZ MemToXMS03 ; Error out if error.
XCHG DI,CX ;
MOV AL,ES:[BX+DI] ; Get the odd memory byte.
XCHG DI,CX ;
MOV [XMSwordByte],AL ; Set the moved word.
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSwordPUT ; Set address of the move structure.
PUSH BX ;
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
POP BX ;
DEC AX ; Check for errors.
JNZ MemToXMS03 ; Error out if error.
MemToXMS02:
JCXZ MemToXMS04 ; Avoid a zero byte move.
MOV XMSmainPUT.Length,CX ; Set length for the move.
MOV XMSmainPUT.SrcOffset,BX ; Set Memory address.
MOV XMSmainPUT.SrcOffsetX,ES ;
MOV XMSmainPUT.DestOffset,DX ; Set XMS address.
MOV XMSmainPUT.DestOffsetX,DI ;
MOV AH,0BH ; Set the XMS move, function code.
MOV SI,OFFSET XMSmainPUT ; Set address of the move structure.
CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
DEC AX ; Check for errors.
JZ MemToXMS05
MemToXMS03:
MOV AX,XMSmemError ; Set error code if error.
JMP MemToXMS05 ;
MemToXMS04:
XOR AX,AX ;
MemToXMS05:
POP DS
POP ES
POP DI
POP SI
POP DX
POP CX
POP BX
POP BP
RET ; Exit
endproc MemToXMS
SUBTTL Last Page
PAGE+
pwrlolvl_TEXT ENDS
END